package main;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import main.remote.RemoteExecutor;

/**
 * Tasks worker thread
 * 
 */
public class TaskDispatcher {
	Graph graph;
	Executor remoteExecutor = new RemoteExecutor();
	Executor localExecutor = new LocalExecutor();
	
	public TaskDispatcher(Graph graph) {
		this.graph = graph;
	}

	public void kickOff() {
		for (Task task : graph.getTasks()) {
			// Wait for predecessors to complete
			if (task.getPredecessors().size() > 0) {
				for(Task t : task.getPredecessors()) {
					synchronized(t) {
						try {
							while (t.executing) {
								t.wait();
							}
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}
			/* Execute this task */
			// Execute using remote strategy, if possible
			CountDownLatch latch = new CountDownLatch(1);
			boolean remoteStatus = remoteExecutor.execute(task);
			// Wait for this task to remotely execute???
			/*try {
				latch.await();
			} catch (InterruptedException e) {
				System.err.println(e);
			}*/
			if (remoteStatus){
				// Remove the task when execution completes
				graph.getTasks().element().executing = false;
				graph.getTasks().remove();
				continue;
			}
			// If remote execution fails, take the local strategy
			localExecutor.execute(task);
			// Remove the task when execution completes
			graph.getTasks().remove();
		}
		
		localExecutor.shutdown();

	}
}
